
#include "yield.h"
#include "ieentry.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Reserva memoria e inicializa un int_env_entry.
 * Devuelve 0 en caso de error.
 */
struct int_env_entry* ieentry_new ()
{
    struct int_env_entry* newentry;
    newentry = (struct int_env_entry*) malloc (sizeof(struct int_env_entry));
    if (newentry)
    {
        newentry -> key = NULL;
    yield0();
        newentry -> value = NULL;
        return newentry;
    }
    else
        return 0;
}


/* Libera la memoria reservada
 */
void ieentry_destroy(struct int_env_entry* este)
{
    free(este -> key);
    yield0();
    free(este -> value);
    free(este);
}

/* Asigna los valores de clave y valor dados al entry.
 * Hace una copia de las cadenas suministradas que **Deben ser null-terminated**
 * as�que pueden ser variables locales, liberadas a posteriori o lo que sea.
 * Devuelve 0 en caso de �ito, 1 en caso de error.
 */
int ieentry_assign (struct int_env_entry* este, const char* key, const char* value)
{
    if (key)
    {
    yield0();
        este -> key = realloc (este -> key, strlen(key) + 1);
        if (este -> key)
            strcpy (este -> key, key);
        else
            return 1;
    }
    if (value)
    {
    yield0();
        este -> value = realloc (este -> value, strlen(value) + 1);
        if (este -> value)
            strcpy (este -> value, value);
        else
            return 1;
    }
    return 0;
}

/* Copia el contenido de SRC a DEST.  **DEST debe estar inicializado**/
void ieentry_copy(struct int_env_entry* dest, struct int_env_entry* src)
{
    dest -> key = realloc(dest -> key, strlen(src -> key) + 1);
    dest -> value = realloc(dest -> value, strlen(src -> value) + 1);
    yield0();
    strcpy (dest -> key, src -> key);
    strcpy (dest -> value, src -> value);
    yield0();
}

/* Modifica el valor del entry, sin alterar la clave.
 * Hace una copia de la cadena, que **Debe ser null-terminated**
 * Devuelve 0 en caso de �ito, 1 en caso de error.
 */
int ievalue_update (struct int_env_entry* este, char* value)
{
    este -> value = realloc (este -> value, strlen(value) + 1);
    if (este -> value)
    {
        strcpy (este -> value, value);
    yield0();
        return 0;
    }
    else
        return 1;
}

/* Compara las dos claves.  Devuelve -1, 0 �1 si la clave DOS es
 * respectivamente menor, igual o mayor que la clave UNO.
 */
int iekey_compare(struct int_env_entry* uno, struct int_env_entry* dos)
{
  return strcmp(uno -> key, dos -> key);
}

/* Devuelve un char* de la representaci� del par KEY = VALUE para esta 
 * del entorno interno; es para uso con rbtshow, ver rbtree.h. 
 */
char* ieentry_show(struct int_env_entry* este)
{
    char* ptr = 0;
    if (este)
    {
        ptr = (char*) malloc (strlen (este -> key) + strlen (este -> value) + 5);
    yield0();
        strcpy(ptr, este -> key);
        strcat(ptr, " = ");
    yield0();
        strcat(ptr, este -> value);
    }
    return ptr;
}

char *ieentry_copy_val (struct int_env_entry* este)
{
    /* strdup no es ANSI C */
    return strdup(este->value);
}

char *ieentry_rob_val (struct int_env_entry* este)
{
    char *retval = este->value;
    este->value = 0;
    return retval;
}
